/*
 * @Author: AiLjx
 * @Date: 2022-06-28 21:13:11
 * @LastEditors: AiLjx
 * @LastEditTime: 2022-06-29 21:04:47
 */
const express = require("express");
const { buildSchema } = require("graphql");
const graphqlHttp = require("express-graphql");

// 在sercer目录下打开终端，nodemon .\04-db.js启动

// 先启动本地mongodb！！！
//-------------链接数据库服务------------------------
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/graphql", {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});

/*
  1. 创建模型
  2. 操作数据库
*/
// 创建模型film，供mongodb使用
// 限制 数据库这个films（集合/表） 只能存下面这三个字段
var FilmModel = mongoose.model(
    "film",
    new mongoose.Schema({
        name: String,
        poster: String,
        price: Number,
    })
);

// 创建
// FilmModel.create
// 查询
// filmModel.find
// 更新
// FilmModel.update
// 删除
// FimlModel.delete
//-------------------------------------

// 描述语句
// 注意FilmInput，它是用户传来的字段的类型，前面用input定义
var Scchema = buildSchema(`

   type Film{
       id:String,
       name:String,
       poster:String,
       price:Int
   }

   input FilmInput{
        name:String,
        poster:String,
        price:Int
   }

   type Query{
       getNowplayingList(id:String):[Film]
    }

    type Mutation{
        createFilm(input: FilmInput):Film,
        updateFilm(id:String!,input:FilmInput):Film,
        deleteFilm(id:String!):Int
    }
`);
//处理器
const root = {
    getNowplayingList({ id }) {
        // 基于模型操作数据库
        // 操作数据的语句是一个promise对象
        // graphql支持直接return一个promise对象
        if (id) {
            return FilmModel.find({ _id: id });
        }
        return FilmModel.find();
    },

    createFilm({ input }) {
        return FilmModel.create({
            ...input,
        }).then((res) => {
            console.log(res);
            return res;
        });
    },
    updateFilm({ id, input }) {
        // updateMany 匹配多个
        return (
            FilmModel.updateOne(
                {
                    _id: id,
                },
                {
                    ...input,
                }
            )
                // FilmModel.find返回的是一个数组，我们在描述语句中定义的updateFilm返回的是一个对象
                // 所以需要取出数组元素
                .then((res) => FilmModel.find({ _id: id }))
                .then((res) => res[0])
        );
    },

    deleteFilm({ id }) {
        // deleteMany 匹配多个
        return FilmModel.deleteOne({ _id: id }).then((res) => 1);
    },
};

var app = express();
app.use(
    "/graphql",
    graphqlHttp({
        schema: Scchema,
        rootValue: root,
        graphiql: true,
    })
);

//配置静态资源目录，在home.html中利用原生JS测试graphql
// 访问http://localhost:3001/home.html
app.use(express.static("public"));

app.listen(3001);
